package com.jessechanrui.template.common.template.auth.websocket;


import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class WebSocketSessionManager {

    // 存储标准WebSocket会话，key: sessionId, value: WebSocketSession
    private final Map<String, org.springframework.web.socket.WebSocketSession> standardSessions = new ConcurrentHashMap<>();

    // 存储响应式WebSocket会话，key: sessionId, value: Reactive WebSocketSession
    private final Map<String, org.springframework.web.reactive.socket.WebSocketSession> reactiveSessions = new ConcurrentHashMap<>();

    // 会话元数据存储，记录会话创建时间等信息
    private final Map<String, SessionMetadata> sessionMetadata = new ConcurrentHashMap<>();

    /**
     * 注册标准WebSocket会话
     */
    public void registerStandardSession(String sessionId, org.springframework.web.socket.WebSocketSession session) {
        if (sessionId == null || session == null) {
            log.warn("Cannot register session with null sessionId or session");
            return;
        }

        standardSessions.put(sessionId, session);
        sessionMetadata.put(sessionId, new SessionMetadata(
                sessionId,
                SessionType.STANDARD,
                new Date(),
                session.getRemoteAddress().toString()
        ));

        log.info("Registered standard session: {} (total: {})",
                sessionId, standardSessions.size());
    }

    /**
     * 注册响应式WebSocket会话
     */
    public void registerReactiveSession(String sessionId, org.springframework.web.reactive.socket.WebSocketSession session) {
        if (sessionId == null || session == null) {
            log.warn("Cannot register session with null sessionId or session");
            return;
        }

        reactiveSessions.put(sessionId, session);
        sessionMetadata.put(sessionId, new SessionMetadata(
                sessionId,
                SessionType.REACTIVE,
                new Date(),
                session.getHandshakeInfo().getRemoteAddress().toString()
        ));

        log.info("Registered reactive session: {} (total: {})",
                sessionId, reactiveSessions.size());
    }

    /**
     * 移除标准WebSocket会话
     */
    public void removeStandardSession(String sessionId) {
        if (sessionId == null) return;

        org.springframework.web.socket.WebSocketSession removed = standardSessions.remove(sessionId);
        if (removed != null) {
            sessionMetadata.remove(sessionId);
            log.info("Removed standard session: {} (remaining: {})",
                    sessionId, standardSessions.size());
        }
    }

    /**
     * 移除响应式WebSocket会话
     */
    public void removeReactiveSession(String sessionId) {
        if (sessionId == null) return;

        org.springframework.web.reactive.socket.WebSocketSession removed = reactiveSessions.remove(sessionId);
        if (removed != null) {
            sessionMetadata.remove(sessionId);
            log.info("Removed reactive session: {} (remaining: {})",
                    sessionId, reactiveSessions.size());
        }
    }

    /**
     * 获取标准WebSocket会话
     */
    public org.springframework.web.socket.WebSocketSession getStandardSession(String sessionId) {
        if (sessionId == null) return null;
        return standardSessions.get(sessionId);
    }

    /**
     * 获取响应式WebSocket会话
     */
    public org.springframework.web.reactive.socket.WebSocketSession getReactiveSession(String sessionId) {
        if (sessionId == null) return null;
        return reactiveSessions.get(sessionId);
    }

    /**
     * 检查会话是否存在
     */
    public boolean sessionExists(String sessionId) {
        if (sessionId == null) return false;
        return standardSessions.containsKey(sessionId) || reactiveSessions.containsKey(sessionId);
    }

    /**
     * 获取会话类型
     */
    public SessionType getSessionType(String sessionId) {
        if (sessionId == null) return null;

        if (standardSessions.containsKey(sessionId)) {
            return SessionType.STANDARD;
        } else if (reactiveSessions.containsKey(sessionId)) {
            return SessionType.REACTIVE;
        }
        return null;
    }

    /**
     * 获取所有活跃会话ID
     */
    public List<String> getAllSessionIds() {
        List<String> allSessions = new ArrayList<>(standardSessions.keySet());
        allSessions.addAll(reactiveSessions.keySet());
        return allSessions;
    }

    /**
     * 获取指定类型的所有会话ID
     */
    public List<String> getSessionIdsByType(SessionType type) {
        if (type == SessionType.STANDARD) {
            return new ArrayList<>(standardSessions.keySet());
        } else if (type == SessionType.REACTIVE) {
            return new ArrayList<>(reactiveSessions.keySet());
        }
        return Collections.emptyList();
    }

    /**
     * 获取所有会话的元数据
     */
    public List<SessionMetadata> getAllSessionMetadata() {
        return new ArrayList<>(sessionMetadata.values());
    }

    /**
     * 获取会话元数据
     */
    public SessionMetadata getSessionMetadata(String sessionId) {
        return sessionMetadata.get(sessionId);
    }

    /**
     * 关闭所有会话
     */
    public void closeAllSessions() {
        // 关闭标准会话
        standardSessions.forEach((id, session) -> {
            try {
                if (session.isOpen()) {
                    session.close();
                    log.info("Closed standard session: {}", id);
                }
            } catch (Exception e) {
                log.error("Error closing standard session {}: {}", id, e.getMessage());
            }
        });
        standardSessions.clear();

        // 关闭响应式会话
        reactiveSessions.forEach((id, session) -> {
            try {
//                session.close().subscribe(
//                        () -> System.out.println(""),
//                        error -> log.error("Error closing reactive session {}: {}", id, error.getMessage())
//                );
            } catch (Exception e) {
                log.error("Error closing reactive session {}: {}", id, e.getMessage());
            }
        });
        reactiveSessions.clear();

        sessionMetadata.clear();
        log.info("All sessions have been closed");
    }

    /**
     * 会话类型枚举
     */
    public enum SessionType {
        STANDARD, REACTIVE
    }

    /**
     * 会话元数据类
     */
    public static class SessionMetadata {
        private final String sessionId;
        private final SessionType type;
        private final Date creationTime;
        private final String remoteAddress;
        private Date lastActivityTime;

        public SessionMetadata(String sessionId, SessionType type, Date creationTime, String remoteAddress) {
            this.sessionId = sessionId;
            this.type = type;
            this.creationTime = creationTime;
            this.remoteAddress = remoteAddress;
            this.lastActivityTime = creationTime;
        }

        // 更新最后活动时间
        public void updateLastActivity() {
            this.lastActivityTime = new Date();
        }

        // Getters
        public String getSessionId() {
            return sessionId;
        }

        public SessionType getType() {
            return type;
        }

        public Date getCreationTime() {
            return creationTime;
        }

        public String getRemoteAddress() {
            return remoteAddress;
        }

        public Date getLastActivityTime() {
            return lastActivityTime;
        }

        @Override
        public String toString() {
            return "SessionMetadata{" +
                    "sessionId='" + sessionId + '\'' +
                    ", type=" + type +
                    ", creationTime=" + creationTime +
                    ", remoteAddress='" + remoteAddress + '\'' +
                    ", lastActivityTime=" + lastActivityTime +
                    '}';
        }
    }
}


